﻿#include <stdarg.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <time.h>
#include "keymng_msg.h"
#include "itcast_asn1_der.h"

void freeTeacherKey(Teacher** pTeacher)
{
	if (pTeacher == NULL)
	{
		return;
	}
	if (*pTeacher != NULL)
	{
		if ((*pTeacher)->p != NULL)
		{
			free((*pTeacher)->p);
			(*pTeacher)->p = NULL;
		}
		free(*pTeacher);
		*pTeacher = NULL;
	}
}

//3.传入，传出，传入传出；
//int TeacherEncode(Teacher* pTeacher, unsigned char** out, int* outlen)
int TeacherEncodeKey(Teacher* pTeacher, ITCAST_ANYBUF** outData)
{
	/*unsigned char* tmp = malloc(32);
	strcpy(tmp, "xxxxxyyyyy");
	*out = tmp;
	*outlen = strlen(tmp);*/

	int					ret = 0;
	ITCAST_ANYBUF* pTmp = NULL, * pHeadBuf = NULL;
	ITCAST_ANYBUF* pTmpBuf = NULL;
	ITCAST_ANYBUF* pOutData = NULL;

	unsigned char* tmpOut = NULL;
	int					tmpOutLen = 0;

	//4.将char*类型的name转换成ITCAST_ANYBUF类型；
	ret = DER_ITCAST_String_To_AnyBuf(&pTmpBuf, pTeacher->name, strlen(pTeacher->name));
	if (ret != 0)
	{
		printf("DER_ITCAST_String_To_AnyBuf error: %d\n", ret);
		return ret;
	}

	//5.编码name --> TLV；
	ret = DER_ItAsn1_WritePrintableString(pTmpBuf, &pHeadBuf);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pTmpBuf);
		printf("DER_ItAsn1_WritePrintableString error: %d\n", ret);
		return ret;
	}
	DER_ITCAST_FreeQueue(pTmpBuf);

	pTmp = pHeadBuf;
	//6.编码age；
	ret = DER_ItAsn1_WriteInteger(pTeacher->age, &(pTmp->next));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("DER_ItAsn1_WriteInteger error: %d\n", ret);
		return ret;
	}

	pTmp = pTmp->next;
	//7.编码p，char*;
	ret = EncodeChar(pTeacher->p, pTeacher->plen, &(pTmp->next));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("EncodeChar error: %d\n", ret);
		return ret;
	}

	pTmp = pTmp->next;
	//8.编码plen;
	ret = DER_ItAsn1_WriteInteger(pTeacher->plen, &(pTmp->next));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("DER_ItAsn1_WriteInteger error: %d\n", ret);
		return ret;
	}

	//9.编码大结构体；
	ret = DER_ItAsn1_WriteSequence(pHeadBuf, &pOutData);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("DER_ItAsn1_WriteSequence error: %d\n", ret);
		return ret;
	}

	//*out = pOutData->pData;
	/*
		*out = (unsigned char*)malloc(pOutData->dataLen);
		if (*out == NULL)
		{
			ret = 2;
			DER_ITCAST_FreeQueue(pOutData);
			printf("func TeacherEncode() malloc err: %d\n", ret);
			return ret;
		}
		//17.把运算结果copy到新分配的内存块中；
		memcpy(*out, pOutData->pData, pOutData->dataLen);
		*outlen = pOutData->dataLen;
	*/
	//DER_ITCAST_FreeQueue(pOutData);

	//10.老师结构体，大节点，传出来；
	* outData = pOutData;
	//11.释放链表，以免内存泄露；
	DER_ITCAST_FreeQueue(pHeadBuf);

	return 0;
}

int TeacherDecodeKey(unsigned char* indata, int inLen, Teacher** pStruct)
{
	int					ret = 0;
	ITCAST_ANYBUF* pTmp = NULL, * pHead = NULL;
	ITCAST_ANYBUF* pOutData = NULL;
	ITCAST_ANYBUF* tmpAnyBuf = NULL;

	Teacher* pStructTeacher = NULL;

	//12.把c语言buf，转成ITCAST_ANYBUF；
	/*
		tmpAnyBuf = (ITCAST_ANYBUF*)malloc(sizeof(ITCAST_ANYBUF));
		if (tmpAnyBuf == NULL)
		{
			ret = 1;
			printf("func TeacherEncodeKey malloc error: %d\n", ret);
			return ret;
		}
		memset(tmpAnyBuf, 0, sizeof(ITCAST_ANYBUF));

		tmpAnyBuf->pData = (unsigned char*)malloc(inLen);
		if (tmpAnyBuf->pData == NULL)
		{
			DER_ITCAST_FreeQueue(tmpAnyBuf);
			ret = 2;
			printf("func TeacherEncodeKey malloc error: %d\n", ret);
			return ret;
		}
		memcpy(tmpAnyBuf->pData, indata, inLen);
		tmpAnyBuf->dataLen = inLen;
	*/

	//13.转码BER报文，unsigned char* --> ITCAST_ANYBUF；
	ret = DER_ITCAST_String_To_AnyBuf(&tmpAnyBuf, indata, inLen);
	if (ret != 0)
	{
		if (tmpAnyBuf != NULL)
		{
			DER_ITCAST_FreeQueue(tmpAnyBuf);
		}
		printf("Decode DER_ITCAST_String_To_AnyBuf error: %d\n", ret);
		return ret;
	}

	//14.解码大Teacher结构体；
	ret = DER_ItAsn1_ReadSequence(tmpAnyBuf, &pHead);
	if (ret != 0)
	{
		if (tmpAnyBuf != NULL)
			DER_ITCAST_FreeQueue(tmpAnyBuf);

		printf("Decode DER_ItAsn1_ReadSequence error: %d\n", ret);
		return ret;
	}
	DER_ITCAST_FreeQueue(tmpAnyBuf);

	//15.给Teacher结构体malloc空间；
	pStructTeacher = (Teacher*)malloc(sizeof(Teacher));
	if (pStructTeacher == NULL)
	{
		DER_ITCAST_FreeQueue(pHead);
		ret = -1;
		printf("Teacher malloc error: %d\n", ret);
		return ret;
	}
	memset(pStructTeacher, 0, sizeof(Teacher));

	pTmp = pHead;
	//16.解码name；
	ret = DER_ItAsn1_ReadPrintableString(pTmp, &pOutData);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherKey(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadPrintableString name error: %d\n", ret);
		return ret;
	}
	//17.ppPrintString->pData; --> name
	memcpy(pStructTeacher->name, pOutData->pData, pOutData->dataLen);

	pTmp = pTmp->next;
	DER_ITCAST_FreeQueue(pOutData);
	//18.解码age；
	ret = DER_ItAsn1_ReadInteger(pTmp, &(pStructTeacher->age));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherKey(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadInteger age error: %d\n", ret);
		return ret;
	}

	pTmp = pTmp->next;
	//19.解码p；
	ret = DER_ItAsn1_ReadPrintableString(pTmp, &pOutData);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherKey(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadPrintableString p error: %d\n", ret);
		return ret;
	}
	//20.给Teacher结构体中的p指针开辟空间；
	pStructTeacher->p = (char*)malloc(pOutData->dataLen + 1);
	if (pStructTeacher->p == NULL)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherKey(&pStructTeacher);
		ret = -2;
		printf("Teacher->p malloc error: %d\n", ret);
		return ret;
	}
	memcpy(pStructTeacher->p, pOutData->pData, pOutData->dataLen);
	//pStructTeacher->p[pOutData->dataLen - 4] = 'R';//编码 != 解码
	pStructTeacher->p[pOutData->dataLen] = '\0';

	pTmp = pTmp->next;
	DER_ITCAST_FreeQueue(pOutData);
	//21.解码plen；
	ret = DER_ItAsn1_ReadInteger(pTmp, &(pStructTeacher->plen));
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHead);
		freeTeacherKey(&pStructTeacher);
		printf("Decode DER_ItAsn1_ReadInteger plen error: %d\n", ret);
		return ret;
	}

	*pStruct = pStructTeacher;
	return 0;
}

//22.对type和Teacher结构体进行编码，封装；
int MsgEncode(
	void* pStruct, /*in*/
	int                type,
	unsigned char** outData, /*out*/
	int* outLen)
{
	ITCAST_ANYBUF* pHeadbuf = NULL, * pTemp = NULL;
	ITCAST_ANYBUF* pOutData = NULL;
	int ret = 0;

	if (pStruct == NULL && type < 0 || outData == NULL || outLen == NULL)
	{
		ret = KeyMng_ParamErr;
		printf("func MsgEncode() err: %d\n", ret);
		return ret;
	}

	ret = DER_ItAsn1_WriteInteger(type, &pHeadbuf);
	if (ret != 0)
	{
		printf("func DER_ItAsn1_WriteInteger() err: %d\n", ret);
		return ret;
	}

	//1.编码type；
	switch (type)
	{
	case ID_MsgKey_Teacher:
		//23.编码老师；
		//TeacherEncodeKey(&t1, &myOut, &mOutlen);
		ret = TeacherEncodeKey((Teacher*)pStruct, &pTemp);
		break;

	case ID_MsgKey_Req:
		//24.密钥请求报文，编码；
		//ret = MsgKey_ReqEncode(密钥请求结构体, Anybuf);
		break;

	case ID_MsgKey_Res:
		//25.密钥应答报文，编码；
		//ret = MsgKey_ResEncode(密钥请求结构体, Anybuf);
		break;

	default:
		ret = KeyMng_ParamErr;
		printf("类型输入失败() itype: %d err: %d\n", type, ret);
		break;
	}

	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadbuf);
		printf("编码失败err: %d\n", ret);
		return ret;
	}

	//2.大结构体 --> AnyBuf；
	pHeadbuf->next = pTemp;
	//26.对type和结构体，再做一次TLV；
	ret = DER_ItAsn1_WriteSequence(pHeadbuf, &pOutData);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadbuf);
		printf("func DER_ItAsn1_WriteSequence() err: %d\n", ret);
		return ret;
	}
	DER_ITCAST_FreeQueue(pHeadbuf);

	*outData = (unsigned char*)malloc(pOutData->dataLen);
	if (*outData == NULL)
	{
		DER_ITCAST_FreeQueue(pOutData);
		ret = KeyMng_ParamErr;
		printf("malloc() err: %d\n", ret);
		return ret;
	}
	memcpy(*outData, pOutData->pData, pOutData->dataLen);
	*outLen = pOutData->dataLen;

	DER_ITCAST_FreeQueue(pOutData);

	return ret;
}

int MsgDecode(
	unsigned char* inData,/*in*/
	int           inLen,
	void** pStruct /*out*/,
	int* type /*out*/)
{
	ITCAST_ANYBUF* pHeadBuf = NULL, * inAnyBuf = NULL;
	int ret = 0;
	unsigned long itype = 0;

	//27.将ber格式的字节流，转换成AnyBuf；
	ret = DER_ITCAST_String_To_AnyBuf(&inAnyBuf, inData, inLen);
	if (ret != 0)
	{
		printf("func DER_ITCAST_String_To_AnyBuf() error: %d\n", ret);
		return ret;
	}

	ret = DER_ItAsn1_ReadSequence(inAnyBuf, &pHeadBuf);
	if (ret != 0)
	{
		printf("func DER_ItAsn1_ReadSequence() err: %d\n", ret);
		return ret;
	}
	DER_ITCAST_FreeQueue(inAnyBuf);

	//28.解析type；
	ret = DER_ItAsn1_ReadInteger(pHeadBuf, &itype);
	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("func DER_ItAsn1_ReadInteger() err: %d\n", ret);
		return ret;
	}

	switch (itype)
	{
	case ID_MsgKey_Teacher:
		//29.解码教师结构体；
		ret = TeacherDecodeKey(pHeadBuf->next->pData, pHeadBuf->next->dataLen, (Teacher**)pStruct);
		break;
	case ID_MsgKey_Req:
		//30.解码，请求报文；
		break;
	case ID_MsgKey_Res:
		//31.解码，应答报文；
		break;
	default:
		ret = KeyMng_TypeErr;
		printf("itype: %d失败 :%d\n", itype, ret);
		break;
	}

	if (ret != 0)
	{
		DER_ITCAST_FreeQueue(pHeadBuf);
		return ret;
	}

	*type = itype;
	DER_ITCAST_FreeQueue(pHeadBuf);

	return ret;
}

int MsgMemFree(void** point, int type)
{
	if (point == NULL)
	{
		return 0;
	}

	//32.释放Encode编码以后的内存块；
	if (type == 0)
	{
		if (*point)free(*point);
		*point = NULL;
		return 0;
	}

	switch (type)
	{
	case ID_MsgKey_Teacher:
		freeTeacherKey((Teacher**)point);
		break;
	case ID_MsgKey_Req:
		//freeTeacherKey((Teacher**)point);
		break;
	case ID_MsgKey_Res:
		//freeTeacherKey((Teacher**)point);
		break;
	default:
		break;
	}


	return 0;
}
